﻿/// <Summary> 
/// $Author: Nikhil Chinchwade 
/// This file contains classes to represnt an Azure application deployment
/// </Summary>>
/// 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.StorageClient.Protocol;
using Microsoft.WindowsAzure.StorageClient.Tasks;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.Diagnostics.Management;
using Microsoft.WindowsAzure.Diagnostics;
using System.Windows;
using System.Collections;

namespace MindTree.PerfWorkbench.Azure.Monitor.Core
{
    /// <summary>
    /// Represents an Azure application deployment
    /// </summary>
    public class AzureAppDeployment
    {
        private List<AzureRole> roles = new List<AzureRole>();

        /// <summary>
        /// List of azure roles configured under the current azure application
        /// </summary>
        public List<AzureRole> Roles
        {
            get
            {
                return roles;
            }
            set
            {
                roles = value;
            }
        }

        /// <summary>
        /// Default Constructor
        /// </summary>
        public AzureAppDeployment()
        {
        }

        /// <summary>
        /// Parameterised Constructor
        /// </summary>
        /// <param name="paramApp"></param>
        public AzureAppDeployment(AzureAppDeployment paramApp)
        {
            foreach (AzureRole role in paramApp.Roles)
            {
                this.Roles.Add(new AzureRole(role));
            }
        }

        public int CounterSetIndex;

        public static int MonitoringInterval = 5;

        /// <summary>
        /// Get the azure role instance id from the current azure app deployment configuration
        /// </summary>
        /// <param name="paramInstId">Azure role instance id</param>
        /// <returns>AzureRoleInstance object</returns>
        public AzureRoleInstance GetRoleInstanceByInstanceId(string paramInstId)
        {
            foreach (AzureRole rl in Roles)
            {
                IEnumerable<AzureRoleInstance> rlIns = rl.Instances.Where(a => a.RoleInstanceId.Equals(paramInstId));
                int cnt = rl.Instances.Where(a => a.RoleInstanceId.Equals(paramInstId)).Count();
                
                if ( cnt == 1 )
                {
                    return rlIns.FirstOrDefault();
                    //return rl.Instances.Where(a => a.RoleInstanceId.Equals(paramInstId)) as AzureRoleInstance;
                }
            }
            

            return null;
        }

        /// <summary>
        /// Apply the modified configuration from data structure to current Azure live deployment
        /// </summary>
        public void ApplyModifiedConfig()
        {
            foreach (AzureRole role in Roles)
            {
                foreach (AzureRoleInstance instance in role.Instances)
                {
                    instance.ApplyModifiedConfig();
                }
            }
        }
    }

    /// <summary>
    /// Class representing Azure Role
    /// </summary>
    public class AzureRole
    {
        private string roleName;
        /// <summary>
        /// Name of the Role
        /// </summary>
        public string RoleName
        {
            get
            {
                return roleName;
            }
            set
            {
                roleName = value;
            }
        }
        
        private List<AzureRoleInstance> instances = new List<AzureRoleInstance>();

        /// <summary>
        /// List of Azure Instances configured under the current Azure Role
        /// </summary>
        public List<AzureRoleInstance> Instances
        {
            get
            {
                return instances;
            }
            set
            {
                instances = value;
            }
        }

        /// <summary>
        /// Parameterised Constructor
        /// </summary>
        /// <param name="paramRoleName">Name of the Role as String</param>
        public AzureRole(string paramRoleName)
        {
            RoleName = paramRoleName;
        }
        
        /// <summary>
        /// Parameterised Constructor
        /// </summary>
        /// <param name="paramRole">AzureRole object</param>
        public AzureRole(AzureRole paramRole)
        {
            this.RoleName = paramRole.RoleName;
            foreach (AzureRoleInstance inst in paramRole.Instances)
            {
                this.Instances.Add(new AzureRoleInstance(inst));
            }
        }

        public int CounterSetIndex;

        /// <summary>
        /// String representation of the Azure Role
        /// </summary>
        /// <returns>Azure Role Name as String</returns>
        public override string ToString()
        {
            return RoleName;
        }
    }

    /// <summary>
    /// This class represents an Azure Role instance object
    /// </summary>
    public class AzureRoleInstance
    {
        private string roleInstanceId;

        /// <summary>
        /// Azure Role Instance Id
        /// </summary>
        public string RoleInstanceId
        {
            get
            {
                return roleInstanceId;
            }
            set
            {
                roleInstanceId = value;
            }
        }
        
        /// <summary>
        /// Name of the Role
        /// </summary>
        public string RoleName
        {
            get;
            set;
        }

        /// <summary>
        /// Name of the Application
        /// </summary>
        public string AppName
        {
            get;
            set;
        }

        private List<Boolean> ischecked = new List<Boolean>();

        /// <summary>
        /// 
        /// </summary>
        public List<Boolean> IsChecked
        {
            get
            {
                return ischecked;
            }
            set
            {
                ischecked = value;
            }
        }

        private RoleInstanceDiagnosticManager roleInstanceDiagMgr;

        /// <summary>
        /// Azure Role Instance Diagnostics Manager 
        /// </summary>
        public RoleInstanceDiagnosticManager RoleInstanceDiagMgr
        {
            get
            {
                return roleInstanceDiagMgr;
            }
            set
            {
                roleInstanceDiagMgr = value;
            }
        }
        
        /// <summary>
        /// Parameterised constructor
        /// </summary>
        /// <param name="paramRoleInstanceId">RoleInstanceId</param>
        /// <param name="paramDiagMgr">Diagnostics Manager object</param>
        public AzureRoleInstance(string paramRoleInstanceId, RoleInstanceDiagnosticManager paramDiagMgr)
        {
            RoleInstanceId = paramRoleInstanceId;
            RoleInstanceDiagMgr = paramDiagMgr;
            DiagnosticMonitorConfiguration conf = RoleInstanceDiagMgr.GetCurrentConfiguration();

            //IsChecked.Add(true);
            //Ischecked.Add(false);
            //conf.PerformanceCounters.DataSources[0].
        }
        
        /// <summary>
        /// Parameterised Constructor
        /// </summary>
        /// <param name="paramInst">Azure Role instance object</param>
        public AzureRoleInstance(AzureRoleInstance paramInst)
        {
            //AzureRoleInstance this = new AzureRoleInstance(paramInst.RoleInstanceId, paramInst.RoleInstanceDiagMgr);
            this.RoleInstanceDiagMgr = paramInst.RoleInstanceDiagMgr;
            this.RoleInstanceId = paramInst.RoleInstanceId;
            this.AppName = paramInst.AppName;
            foreach (int key in paramInst.counterSetIndex)
            {
                this.CounterSetIndex.Add(key);// = paramInst.counterSetIndex;
            }
            this.IsChecked = paramInst.IsChecked;
            this.RoleName = paramInst.RoleName;           

        }

        /// <summary>
        /// Get the performance counters from AzureRoleInstance diagnostics Manager
        /// </summary>
        /// <returns>List of Performance Counters</returns>
        public IList<PerfCounter> GetCounters()
        {           
           return  CounterSets.GetCounters(RoleInstanceDiagMgr.GetCurrentConfiguration().PerformanceCounters.DataSources);
           
        }


        public override string ToString()
        {
            return RoleInstanceId; 
        }

        public void SelectionChanged(object sender, RoutedEventArgs e)
        {

        }

        private List<int> counterSetIndex = new List<int>();

        public List<int> CounterSetIndex
        {
            get
            {
                return counterSetIndex;
            }
            set
            {
                counterSetIndex = value;
            }
        }

        public void ApplyModifiedConfig()
        {
            IList<PerformanceCounterConfiguration> counters = new List<PerformanceCounterConfiguration>();
            foreach (int i in CounterSetIndex)
            {                
                foreach (PerfCounter cntr in AzureMonInstanceContext.ConfigCountersets.CtrSets[i].Counters)
                {
                    PerformanceCounterConfiguration cnfig = new PerformanceCounterConfiguration();
                    cnfig.CounterSpecifier = cntr.ToString();
                    cnfig.SampleRate = TimeSpan.FromSeconds(AzureAppDeployment.MonitoringInterval);
                    if (!counters.Contains(cnfig))
                    {
                        counters.Add(cnfig);                        
                    }                        
                }                             
            }
            
            DiagnosticMonitorConfiguration monConfig = RoleInstanceDiagMgr.GetCurrentConfiguration();
            monConfig.PerformanceCounters.DataSources.Clear();
            foreach (PerformanceCounterConfiguration cntrconfig in counters)
            {
                monConfig.PerformanceCounters.DataSources.Add(cntrconfig);
            }
            RoleInstanceDiagMgr.SetCurrentConfiguration(monConfig);
        }
    }
    
    public class AzureApp
    {
        private List<AzureAppDeployment> appDeployment = new List<AzureAppDeployment>();
        
        public List<AzureAppDeployment> AppDeployment
        {
            get
            {
                return appDeployment;   
            }
            set
            {
                appDeployment = value;
            }
        }             

        public AzureAppConnectionConfig AppConnectionConfig
        {
            get;
            set;
        }

        public AzureApp(AzureAppConnectionConfig paramConnConfig)
        {
            AppConnectionConfig = paramConnConfig;
            AppConnectionConfig = new AzureAppConnectionConfig();
            AppDeployment.Add( new AzureAppDeployment() );
        }

        public AzureApp()
        {
            AppConnectionConfig = new AzureAppConnectionConfig();
            AppDeployment.Add(new AzureAppDeployment());
        }

        public void ReloadDeploymentConfig()
        {

        }
    }
    
    public class AzureAppConnectionConfig
    {
        //private int monUiUpdateIntervalInSec = 60;

        //public int MonUiUpdateIntervalInSec
        //{
        //    get
        //    {
        //        return monUiUpdateIntervalInSec;
        //    }
        //    set
        //    {
        //        monUiUpdateIntervalInSec = value;
        //    }
        //}

        /*private StorageCredentialsAccountAndKey storageAccount = new StorageCredentialsAccountAndKey("ptfram", "mUn+yQmY9c1X9X7OhQe4pFUjaeXhHhAEKooQdTwk7PByyFAtAx4dhl42t05RlUYc5X1vCnobSegvzP6Zh3Qfgw==");

        public StorageCredentialsAccountAndKey StorageAccount
        {
            get
            {
                return storageAccount;
            }
            set
            {
                storageAccount = value;
            }
        }*/

        private string accountName;

        public string AccountName
        {
            get
            {
                return accountName;
            }
            set
            {
                accountName = value;
            }
        }

        private string accountKey;

        public string AccountKey
        {
            get
            {
                return accountKey;
            }
            set
            {
                accountKey = value;
            }
        }

        private string tableBaseAddress ;

        public string TableBaseAddress
        {
            get
            {
                if (!String.IsNullOrEmpty(AccountName))
                {
                    tableBaseAddress = "http://" + AccountName + ".table.core.windows.net/";
                }
                return tableBaseAddress;
            }
            set
            {
                tableBaseAddress = value;
            }
        }

        private String appDeploymentId;

        public String AppDeploymentId
        {
            get
            {
                return appDeploymentId;
            }
            set
            {
                appDeploymentId = value;
            }
        }
    }

}
